#※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
# File Name: cmd.sh
# Author: GID5564
# Description: function for install package
# Created Time: 17/11/23-22:24:55
#※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
#! /usr/bin/env bash

# 避免重复导入
#[[ -n $__XLIB_IMPORTED__CMD ]] && return 0
#__XLIB_IMPORTED__CMD=1
export BOOT_CALL=${BASH_SOURCE[0]:-$0}
function __cmd_init__() {
    export CALL_BASE_PATH=$(cd "$(dirname "${BOOT_CALL}")" &>/dev/null && pwd -P)
    
    export PY_FUNCTION_PATH="$(dirname $CALL_BASE_PATH)/pylib/exa"
    
    export CMD_PIP_INSTALL="python3 -m pip install -i ${MODE_SOURCE} "
    export CMD_INSTALL="sudo apt install -y "
}


#这个脚本定义了一个接受函数名和参数的函数“demo”。
#并将带有参数的函数调用打印为字符串。
function demo_test(){
    local func_name=$1
    shift
    declare -a arguments=("$@")
    args_str=""
    for arg in "${arguments[@]}"; do
        args_str+="'${arg}',"
    done
    args_str=${args_str%?}  # Remove the trailing comma

    local cmd="${func_name}(${args_str})"
    echo "${cmd}"
}
########################################
# 描述: 超时执行命令
# 参数: $1:function_name,命令或函数名称
#       $2:time_out,超时时间(s)，默认3s
# 返回: 
# 实例: timeout_command
########################################
function timeout_command() {
    [[ -z "$1" ]] && {
        error "Usage: timeout_command <cmd or function name> [time out]"
        return $INVALID_ARGUMENTS
    }
    local function_name=$1
    local time_out=${2:-3}
    # 使用timeout命令执行给定的函数，如果超过指定的时间，则执行function_name
    timeout ${time_out}s bash -c "$function_name"
    unset function_name time_out
    
}


########################################
# 描述: 定义延迟执行函数
# 参数: $1:command_to_run,命令或函数名称
#       $2:delay_seconds,延时时间(s)，默认5s
# 返回: 
# 实例: delay_command
########################################
function delay_command() {
    # 参数校验
    [[ -z $1 ]]&&{
        echo "用法: delay_command <命令或函数名> <延迟秒数>"
        return 1
    }

    local command_to_run="$1"
    local delay_seconds="${2:-5}"

    # 校验延迟秒数是否为非负整数
    if ! [[ "$delay_seconds" =~ ^[0-9]+$ ]]; then
        echo "错误: 延迟秒数必须为非负整数"
        return 1
    fi
    
    local pid=$!
    msg "${BLUE}任务 ${RESET}${RED}${pid} ${RESET}${BLUE}已调度:${RESET}${RED}『$command_to_run』${RESET}${BLUE}将在 ${RESET}${RED}${delay_seconds} ${RESET}${BLUE}秒后执行${RESET},${BLUE}使用${RESET} ${YELLOW}kill $pid ${RESET}${BLUE}终止延迟任务${RESET}"
    
    # 使用子Shell在后台执行延迟逻辑
    (
        sleep "$delay_seconds"       # 等待指定秒数
        eval "$command_to_run"        # 执行命令或函数
    ) 

    unset command_to_run delay_seconds pid
}

########################################
# 描述: 用于调用Python文件中的指定函数。
# 参数: $1：Python文件名，需要包含文件扩展名（如.py）。
#       $@：要执行的Python函数名及其参数，格式为`function_name arg1 arg2 ...)`。
# 返回: 
# 实例: py_call "HttpServer.py" "notify" '通知内容'
########################################
function py_call(){
    local py_file=$1
    shift
    local func_name=$1 
    shift
    [[ -z ${py_file} || -z ${func_name} ]] && {
        error "Usage: py_call <py文件> <函数名称> [参数列表]"
        return $INVALID_ARGUMENTS
    }
    
    # 检测是否带路径，若无则添加前缀
    [[ $py_file =~ ^(/|[^/]+/) ]] || {
        py_file="${PY_FUNCTION_PATH}/${py_file}"
    }    
    [[ ! -s ${py_file} ]] && {
        error "文件无效或路径不正确: ${py_file} "
        return $INVALID_ARGUMENTS
    }
    
    
    #参数
    declare -a arguments=("$@")
    local args_str=""
    for arg in "${arguments[@]}"; do
        args_str+="'${arg}',"
    done
    args_str=${args_str%?}  # Remove the trailing comma

    #local func="${func_name}(${args_str})"
    #获取python函数返回值(return)
    local func="print(${func_name}(${args_str}))"

    #py文件路径
    local py_path=${py_file%/*}
    #文件名称
    local file_name=$(basename "${py_file}")
    file_name=${file_name%.*}

    [[ ${py_path} == ${py_file} ]] && {
        local cmd="from ${file_name} import ${func_name};${func}"
    } || {
        local cmd="import sys;sys.path.append('${py_path}');from ${file_name} import ${func_name};${func}"
    }
    #echo $cmd
    python3 -c ${cmd}
    unset py_file py_path file_name func func_name cmd args_str arguments
}

########################################
# 描述: 选择对话框命令[dialog|whiptail]
# 参数: 
# 返回: 全局变量WINDOW
# 实例: SetDialogBin
########################################
function set_dialog_bin() {
	case $(uname -o) in
	"Android") 
	    if [[ -z $(command -v dialog) ]];then
	        eval "${CMD_INSTALL} dialog"
	    fi
	    export WINDOW="dialog" 
	    ;;
	*) 
	    if [[ -z $(command -v whiptail) ]];then
	        eval "${CMD_INSTALL} whiptail"
	    fi
	    export WINDOW="whiptail" 
	    ;;
	esac
}

function IsCmd() {
    [[ -z "$1" ]] && {
        error "Usage: IsCmd <命令>"
        return $INVALID_ARGUMENTS
    }
    local cmd="$1"
    local f=$(command -v $cmd)
    [[ $f != "" ]] && echo "$cmd: $f" || return $FILE_NOT_FOUND
}

# 调用 $1 $@
function execute() {
    [[ -z "$1" ]] && {
        error "Usage: execute <命令> [参数列表]"
        return $INVALID_ARGUMENTS
    }

    local cmd=$1
    shift
    # NOTE 注意此处的true/false判断
    if command -v -- "$cmd" &>/dev/null; then
        "$cmd" "$@"
    else
        error "函数/命令 '$cmd' 未执行!"
        return $COMMAND_NOT_FOUND
    fi
    unset cmd
}


#判断安装
function apt_install(){
    for pkg in "$@"
    do
        [[ -z $(command -v ${pkg}) ]] && {
            sudo apt install -y ${pkg}
        }
    done
    unset pkg
}

########################################
# 描述: 检测python软件包及依赖包是否已安装
# 参数: $1,软件包名称
# 返回: 1，是；0，不是
########################################
function check_pypkg_installed(){
    [[ -z "$1" ]] && {
        error "Usage: check_pypkg_installed <package name>"
        return $INVALID_ARGUMENTS
    }
    python3 -c "import ${1}" >/dev/null 2>&1 
    [[ $? -eq 0 ]] && echo 1 || echo 0
}

########################################
# 描述: 检测dpkg软件包及依赖包是否已安装
# 参数: $1,软件包名称
# 返回: 1，是；0，不是
########################################
function check_dpkg_installed(){
    [[ -z "$1" ]] && {
        error "Usage: check_dpkg_installed <package name>"
        return $INVALID_ARGUMENTS
    }
    dpkg -s "${1}" >/dev/null 2>&1 
    [[ $? -eq 0 ]] && echo 1 || echo 0
}


########################################
# 描述: 检测安装Python软件包及依赖
# 参数: $1,软件包名称
# 返回: 
########################################
function install_python_package(){
    [[ -z "$1" ]] && {
        error "Usage: install_python_package <package name>"
        return $INVALID_ARGUMENTS
    }
    local pkg=$1
    local installed=$(check_pypkg_installed ${pkg})
    if [[ ${installed} -eq 0 ]];then
        msg "${RED}${pkg}${RESET}${BLUE} 软件包安装中…… ${RESET}" 
        eval "${CMD_PIP_INSTALL} ${pkg}"
    fi
    unset installed
    unset pkg
}

########################################
# 描述: 检测安装dpkg软件包及依赖
# 参数: $1,软件包名称
# 返回: 
########################################
function install_dpkg_package(){
    [[ -z "$1" ]] && {
        error "Usage: install_dpkg_package <package name>"
        return $INVALID_ARGUMENTS
    }
    local pkg=$1
    local installed=$(check_dpkg_installed ${pkg})
    if [[ ${installed} -eq 0 ]];then
        msg "${RED}${pkg}${RESET}${BLUE} 软件包安装中…… ${RESET}" 
        eval "${CMD_INSTALL} ${pkg}"
    fi
    unset installed
    unset pkg
}

########################################
# 描述: 更新dpkg包
# 参数: 
# 返回: 
# 实例: apk_update_source
########################################
function update_dpkg(){
    eval "sudo apt update && sudo apt upgrade -y"
}

########################################
# 描述: 更新python包
# 参数: 
# 返回: 
# 实例: apk_update_source
########################################
function update_pypkg(){
    local pkg=${1:-"pip"}
    msg "${RED}${pkg}${RESET}${BLUE} 软件包更新中…… ${RESET}" 
    python3 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -U ${pkg}
}


########################################
# 描述: 检测安装Python软件包及依赖
# 参数: $1,软件包名称字符串，逗号分隔
# 返回: 
########################################
function install_python_packages(){
    [[ -z "$1" ]] && {
        error "Usage: install_python_packages <package name list>"
        return $INVALID_ARGUMENTS
    }

    #按,分隔
    local pkgs
    #转数组
    pkgs=(`echo $1 | awk -v RS='' '{gsub(","," "); print}'`)
    for item in ${pkgs}
    do
        install_python_package ${item}
    done
    unset pkgs
    unset item
}

########################################
# 描述: 检测安装dpkg软件包
# 参数: $1,软件包名称字符串，逗号分隔
# 返回: 
# 实倒: install_dpkg_packages "vim,curl,wget" 
########################################
function install_dpkg_packages(){
    [[ -z "$1" ]] && {
        error "Usage: install_dpkg_packages <package name list>"
        return $INVALID_ARGUMENTS
    }

    #按,分隔
    local pkgs
    #转数组
    pkgs=(`echo $1 | awk -v RS='' '{gsub(","," "); print}'`)
    for item in ${pkgs}
    do
        install_dpkg_package ${item}
    done
    unset pkgs
    unset item
}




##♥  return返回,0为执行成功，否则失败

function is_cmd_exists() {
    local _cmd_name=$1

    (command -v "$_cmd_name" >/dev/null) && return 0
    return 1
}























__cmd_init__

